#include "stdint.h"
#include "stdio.h"
#include "string.h"
#include "microConfig.h"
#include "microTime.h"
#include "microDelay.h"
#include "microMemory.h"
#include "microTask.h"
#include "microSemaphore.h"


MicroSemaphoreType *ptypeMicroSemaphoreCreat(uint32_t uiValue)
{
    MicroSemaphoreType *ptypeSemaphoreNew = NULL;

    ptypeSemaphoreNew = pvMicroMemCalloc(&g_typeMicroRTOSMemHead, 1, sizeof(MicroSemaphoreType));
    if(ptypeSemaphoreNew == NULL)
        return NULL;

    ptypeSemaphoreNew->value = uiValue;
    cMicroListInit(&(ptypeSemaphoreNew->list), uiValue);

    return ptypeSemaphoreNew;
}

int8_t cMicroSemaphoreReceive(MicroSemaphoreType *ptypeSemaphoreHandle)
{
    MicroTaskType *ptypeTaskCurrent = NULL;

    if(ptypeSemaphoreHandle == NULL)
        return 1;

    ptypeTaskCurrent = ptypeMicroTaskCurrentGet();

    /* 挂起当前任务 */
    cMicroTaskSuspend(ptypeTaskCurrent);

    /* 插入到当前消息链表的最后 */
    cMicroListInsertEnd(&(ptypeSemaphoreHandle->list), &(ptypeTaskCurrent->list));

    return 0;
}

int8_t cMicroSemaphoreSend(MicroSemaphoreType *ptypeSemaphoreHandle, uint32_t uiValue)
{
    MicroListType *ptypeListNow = NULL;
    MicroTaskType *ptypeTaskNow = NULL;

    if(ptypeSemaphoreHandle == NULL)
        return 1;

    ptypeSemaphoreHandle->value = uiValue;

    ptypeListNow = ptypeSemaphoreHandle->list.pNext;

    /* 把本消息链表的任务全部激活 */
    while(ptypeListNow != &(ptypeSemaphoreHandle->list))
    {
        /* 从当前消息链表中移除 */
        cMicroListRemove(ptypeListNow);

        ptypeTaskNow = ptypeListNow->pElement;

        /* 恢复当前任务到就绪链表 */
        cMicroTaskResume(ptypeTaskNow);

        ptypeListNow = ptypeSemaphoreHandle->list.pNext;
    }

    return 0;
}

int8_t cMicroSemaphoreAdd(MicroSemaphoreType *ptypeSemaphoreHandle)
{
    MicroListType *ptypeListNow = NULL;
    MicroTaskType *ptypeTaskNow = NULL;

    if(ptypeSemaphoreHandle == NULL)
        return 1;

    ++ptypeSemaphoreHandle->value;

    ptypeListNow = ptypeSemaphoreHandle->list.pNext;

    /* 把本消息链表的任务按顺序有条件激活 */
    while((ptypeListNow != &(ptypeSemaphoreHandle->list)) && (ptypeSemaphoreHandle->value > 0))
    {
        /* 从当前消息链表中移除 */
        cMicroListRemove(ptypeListNow);

        ptypeTaskNow = ptypeListNow->pElement;

        /* 恢复当前任务到就绪链表 */
        cMicroTaskResume(ptypeTaskNow);

        --ptypeSemaphoreHandle->value;

        ptypeListNow = ptypeSemaphoreHandle->list.pNext;
    }

    return 0;
}
